package scatter.wwd.rest.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.zxing.WriterException;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.mp.api.WxMpQrcodeService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import scatter.area.pojo.po.Area;
import scatter.area.rest.service.IAreaService;
import scatter.common.dict.PublicDictEnums;
import scatter.common.rest.service.IBaseAddUpdateQueryFormServiceImpl;
import scatter.common.rest.tools.HttpClientTool;
import scatter.common.rest.tools.calendar.CalendarUtils;
import scatter.dict.pojo.po.Dict;
import scatter.dict.rest.service.IDictService;
import scatter.file.rest.cloudstorage.service.impl.AliyunCloudStorageServiceImpl;
import scatter.file.rest.tool.FileNeedDeleteTool;
import scatter.wwd.pojo.param.GenerateCardParam;
import scatter.wwd.rest.utils.graphic.ImageUtils;
import scatter.wwd.rest.utils.io.FileUtils;
import scatter.wwd.rest.utils.io.StreamUtils;
import scatter.wwd.pojo.form.UserCardAddForm;
import scatter.wwd.pojo.form.UserCardPageQueryForm;
import scatter.wwd.pojo.form.UserCardUpdateForm;
import scatter.wwd.pojo.form.app.GenerateCardForm;
import scatter.wwd.pojo.po.*;
import scatter.wwd.rest.mapper.UserCardMapper;
import scatter.wwd.rest.service.*;
import scatter.wxmp.pojo.vo.QrCodeTicketVo;
import scatter.wxmp.rest.comm.PublicUtils;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户卡片表 服务实现类
 * </p>
 *
 * @author yw
 * @since 2020-12-08
 */
@Slf4j
@Service
@Transactional
public class UserCardServiceImpl extends IBaseAddUpdateQueryFormServiceImpl<UserCardMapper, UserCard, UserCardAddForm, UserCardUpdateForm, UserCardPageQueryForm> implements IUserCardService {
    /**
     * 汪汪队卡片场景值前缀
     */
    public static final String SCENESTR_PREFIX = "wwd_user_card_";

    @Override
    public void preAdd(UserCardAddForm addForm,UserCard po) {
        super.preAdd(addForm,po);

    }

    @Override
    public void preUpdate(UserCardUpdateForm updateForm,UserCard po) {
        super.preUpdate(updateForm,po);

    }

    @Autowired
    private IDictService iDictService;

    @Autowired
    private IAreaService iAreaService;

    @Autowired
    private IUserParamQrcodeService iUserParamQrcodeService;

    @Autowired
    private AliyunCloudStorageServiceImpl aliyunCloudStorageService;

    @Autowired
    private IUserInfoService iUserInfoService;

    @Autowired
    private IUserTagService iUserTagService;

    @Autowired
    private IUserAlbumService iUserAlbumService;

    @Autowired
    private WxMpService wxMpService;

    @Override
    public void generateCard(GenerateCardParam param) {
        UserInfo userInfo = iUserInfoService.getByUserId(param.getUserId());

        // 获取图片
        List<UserAlbum> albums = iUserAlbumService.getByUserId(param.getUserId());


        String wwdcardbgPath = FileUtils.getPath(UserCardServiceImpl.class) + "wwdcardbg";
        String bgPath = "";
        Color textColor = null;
        Dict gender = iDictService.getById(userInfo.getGenderDictId());
        if (PublicDictEnums.DictGender.f.name().equals(gender.getValue())) {
            bgPath = wwdcardbgPath + File.separator + "female.png";
            textColor = new Color(0, 0, 0);
        } else {
            textColor = new Color(0, 0, 0);
            bgPath = wwdcardbgPath + File.separator + "male.png";
        }
        try {
            BufferedImage bgImage = ImageUtils.createImage(bgPath);
            // 添加图片
            // 主图
            String mainUrl = Optional.ofNullable(param.getMainPicUrl()).orElse(userInfo.getPicUrl());
            if (StringUtils.isNotEmpty(mainUrl)) {
                BufferedImage pressImg = null;
                try {
                    pressImg = ImageUtils.inputStreamToBufferedImage(download(mainUrl, true));
                } catch (IllegalArgumentException e) {
                    log.error("下载主图异常，尝试使用不带参数下载",e);
                    pressImg = ImageUtils.inputStreamToBufferedImage(download(mainUrl, false));
                }
                if (pressImg != null) {
                    int width = 280;
                    if (pressImg.getWidth() > width) {
                        pressImg = Thumbnails.of(pressImg).scale((new Double(width)).doubleValue() / (double) pressImg.getWidth()).asBufferedImage();
                    }
                    int height = 310;
                    if (pressImg.getHeight() > height) {
                        pressImg = ImageUtils.cutImage(pressImg, 0, (pressImg.getHeight() - height) / 2, pressImg.getWidth(), height);
                    }
                    ImageUtils.pressImage(bgImage, pressImg, 400, 150, 1.0f);
                }
            }
            // 小图
            int imgY = 675;
            int imgX = 90;
            int height = 270;
            int normalcount = 0;
            List<String> otherPicUrls = new ArrayList<>(3);
            if (!isEmpty(param.getOtherPicUrls())) {
                otherPicUrls.addAll(param.getOtherPicUrls());
            }
            for (String url : otherPicUrls) {
                if (normalcount >= 3) {
                    break;
                }
                if (StringUtils.isNotEmpty(url)) {
                    BufferedImage pressImg = null;
                    try {
                        pressImg = ImageUtils.inputStreamToBufferedImage(download(url, true));
                    } catch (IllegalArgumentException e) {
                        pressImg = ImageUtils.inputStreamToBufferedImage(download(url, false));
                    }
                    if (pressImg == null) {
                        continue;
                    }
                    int width = 200;
                    if (pressImg.getWidth() > width) {

                        pressImg = Thumbnails.of(pressImg).scale((new Double(width)).doubleValue() / (double) pressImg.getWidth()).asBufferedImage();
                    }
                    if (pressImg.getHeight() > height) {
                        pressImg = ImageUtils.cutImage(pressImg, 0, (pressImg.getHeight() - height) / 2, pressImg.getWidth(), height);
                    }
                    ImageUtils.pressImage(bgImage, pressImg, imgX, imgY, 1.0f);
                    imgX += width + 30;
                    normalcount++;
                }


            }


            String now = "";
            String home = "";
            if (userInfo.getNowAreaId() != null) {
                List<Area> areas = iAreaService.getAllParents(userInfo.getNowAreaId());
                List<Dict> areaTypes = iDictService.listByIds(areas.stream().map(Area::getTypeDictId).collect(Collectors.toList()));
                Map<String, Dict> areaDictMap = areaTypes.stream().collect(Collectors.toMap(Dict::getId, v -> v));

                String provinceName = "";
                String cityName = "";
                for (Area area : areas) {
                    Dict dict = areaDictMap.get(area.getTypeDictId());
                    if (dict != null && dict.getValue().equals(Area.TypeDictItem.province.itemValue())) {
                        provinceName = area.getName();
                    } else if (dict != null && dict.getValue().equals(Area.TypeDictItem.city.itemValue())) {
                        cityName = area.getName();
                    }
                }
                now = StringUtils.stripToEmpty(provinceName) + " " + StringUtils.stripToEmpty(cityName);
            }
            if (userInfo.getHomeAreaId() != null) {
                List<Area> areas = iAreaService.getAllParents(userInfo.getHomeAreaId());
                List<Dict> areaTypes = iDictService.listByIds(areas.stream().map(Area::getTypeDictId).collect(Collectors.toList()));
                Map<String, Dict> areaDictMap = areaTypes.stream().collect(Collectors.toMap(Dict::getId, v -> v));

                String provinceName = "";
                String cityName = "";
                for (Area area : areas) {
                    Dict dict = areaDictMap.get(area.getTypeDictId());
                    if (dict != null && dict.getValue().equals(Area.TypeDictItem.province.itemValue())) {
                        provinceName = area.getName();
                    } else if (dict != null && dict.getValue().equals(Area.TypeDictItem.city.itemValue())) {
                        cityName = area.getName();
                    }
                }
                home = StringUtils.stripToEmpty(provinceName) + " " + StringUtils.stripToEmpty(cityName);
            }
            List<UserTag> userTags = iUserTagService.getByUserId(param.getUserId());
            String hobbyType = "";
            if (!isEmpty(userTags)) {
                List<Dict> tagTypeDicts = iDictService.listByIds(userTags.stream().map(UserTag::getTypeDictId).collect(Collectors.toList()));
                Map<String, Dict> tagTypeMap = tagTypeDicts.stream().collect(Collectors.toMap(Dict::getId, v -> v));
                UserTag userTag = userTags.stream().filter(f -> "hobby_type_parent".equals(tagTypeMap.get(f.getTypeDictId()).getValue())).findFirst().orElse(null);
                if (userTag != null && StringUtils.isNotBlank(userTag.getContent())) {
                    List<Dict> hobbys = iDictService.listByIds(Arrays.asList(userTag.getContent().split(",")));
                    hobbyType = hobbys.stream().map(Dict::getName).collect(Collectors.joining());
                }
            }

            int x = 100;
            int x_center = bgImage.getWidth() / 2 - 70;
            int y = 90;
            int titleFontSize = 20;
            int textFontSize = 16;
            int lineHeight = 30;
            bgImage = ImageUtils.pressText(bgImage, "个人介绍", "宋体", Font.BOLD, textColor, titleFontSize, x_center, y, 1);
            y = 120;
            bgImage = ImageUtils.pressText(bgImage, "昵称/微信：" + StringUtils.stripToEmpty(userInfo.getName()), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "性别：" + StringUtils.stripToEmpty(gender.getName()), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "身高：" + StringUtils.stripToEmpty(userInfo.getHeight()), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "体重：" + StringUtils.stripToEmpty(userInfo.getWeight()), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "婚姻：" + StringUtils.stripToEmpty(iDictService.getNameById(userInfo.getMaritalStatusDictId())), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "家乡在：" + home, "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "目前在：" + now, "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "生日：" + StringUtils.stripToEmpty(CalendarUtils.dateToString(userInfo.getBirthDay())), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "学历：" + StringUtils.stripToEmpty(iDictService.getNameById(userInfo.getEducationDictId())), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            String hourseCity = "";
            if (StringUtils.isNotEmpty(userInfo.getHourseCity())) {
                hourseCity = "(" + userInfo.getHourseCity() + ")";
            }
            bgImage = ImageUtils.pressText(bgImage,
                    "房：" + (userInfo.getIsHasHourse()?"有":"没有") + hourseCity,
                    "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            String carCity = "";
            if (StringUtils.isNotEmpty(userInfo.getCarCity())) {
                carCity = "(" + userInfo.getCarCity() + ")";
            }
            bgImage = ImageUtils.pressText(bgImage,
                    "车：" + (userInfo.getIsHasCar()?"有":"没有") + carCity,
                    "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "抽烟：" + StringUtils.stripToEmpty(iDictService.getNameById(userInfo.getSmokingDictId())), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "喝酒：" + StringUtils.stripToEmpty(iDictService.getNameById(userInfo.getDrinkingDictId())), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            y += lineHeight;
            bgImage = ImageUtils.pressText(bgImage, "标签信息：" + hobbyType, "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
            String descriptionTemp = "补充介绍：" + StringUtils.stripToEmpty(userInfo.getDescription());
            int descriptionLength = descriptionTemp.length();

            String lineDescription = "";
            for (int i = 0; i < descriptionLength; i++) {
                lineDescription += descriptionTemp.charAt(i);
                if (lineDescription.length() == 38 || i + 1 == descriptionLength) {
                    y += lineHeight;
                    bgImage = ImageUtils.pressText(bgImage, lineDescription, "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
                    lineDescription = "";
                }
            }

            y = 970;
            bgImage = ImageUtils.pressText(bgImage, "择偶标准/理想类型", "宋体", Font.BOLD, textColor, titleFontSize, x_center, y, 1);
            y += 30;
            lineDescription = "";
            String stardardTemp = "  " + StringUtils.stripToEmpty(userInfo.getStandard());
            descriptionLength = stardardTemp.length();
            for (int i = 0; i < descriptionLength; i++) {
                lineDescription += stardardTemp.charAt(i);
                if (lineDescription.length() == 38 || i + 1 == descriptionLength) {
                    y += lineHeight;
                    bgImage = ImageUtils.pressText(bgImage, StringUtils.stripToEmpty(lineDescription), "宋体", Font.BOLD, textColor, textFontSize, x, y, 1);
                    lineDescription = "";
                }
            }

            // 现在使用永久二维码
            UserParamQrcode paramQrcodePo = iUserParamQrcodeService.getByUserId(param.getUserId());
            wxMpService.switchover(param.getAppCode());
            WxMpQrcodeService qrcodeService = wxMpService.getQrcodeService();
            // TODO: 6/17/21
             if (paramQrcodePo == null) {
                //生成微信带参数二维码，以关注公众帐号
                 WxMpQrCodeTicket wxMpQrCodeTicket = qrcodeService.qrCodeCreateLastTicket(SCENESTR_PREFIX + param.getUserId());
                 // String qrCodePictureUrl = qrcodeService.qrCodePictureUrl(wxMpQrCodeTicket.getTicket());
                 UserParamQrcode userParamQrcode = new UserParamQrcode();
                 userParamQrcode.setUserId(param.getUserId());
                 userParamQrcode.setTicket(wxMpQrCodeTicket.getTicket());
                 userParamQrcode.setExpireSeconds(wxMpQrCodeTicket.getExpireSeconds());
                 // 二维码内容
                 userParamQrcode.setContent(wxMpQrCodeTicket.getUrl());
                 userParamQrcode.setIsPermanent(true);
                 // userParamQrcode.setUrl(qrCodePictureUrl);
                 iUserParamQrcodeService.save(userParamQrcode);
                 paramQrcodePo = userParamQrcode;
            }

            // 自己生成带参数的二维码
            int margin = 50;
            int footheight = 150;
            try {
                BufferedImage logo = ImageUtils.createImage(wwdcardbgPath + File.separator + "logo.png");
                BufferedImage templogo = ImageUtils.zoomEqualRatioImageByWidth(logo, 40);
                BufferedImage qrcode = ImageUtils.createQrCodeWithLogo(footheight,
                        paramQrcodePo.getContent(),
                        "utf-8", 0,
                        Color.white, Color.BLACK, templogo);

                ImageUtils.pressImage(bgImage, qrcode, bgImage.getWidth() - qrcode.getWidth() - margin, bgImage.getHeight() - qrcode.getHeight() - margin, 1.0f);

                // 添加logo
                logo = ImageUtils.createImage(wwdcardbgPath + File.separator + "logo-mini.png");
                ImageUtils.pressImage(bgImage, logo, margin, bgImage.getHeight() - logo.getHeight() - margin, 1.0f);

                // 中间文字
                String word = "• 缘 分 从 这 一 刻 开 始 •";
                int fontSize = 26;
                int heightTemp = bgImage.getHeight() - (margin + footheight) / 2 - fontSize / 2 - 25;
                bgImage = ImageUtils.pressText(bgImage, word, "宋体", Font.BOLD, textColor,
                        fontSize,
                        bgImage.getWidth() / 2 - (8 * fontSize + fontSize * 11 / 2) / 2,// 8个中文字符11个英语字符
                        heightTemp,
                        1);
                word = "扫码进入公众号  相识更多单身男生女生";
                int fontSizeTemp = 17;

                bgImage = ImageUtils.pressText(bgImage, word, "宋体", Font.PLAIN, textColor,
                        fontSizeTemp,
                        bgImage.getWidth() / 2 - (18 * fontSizeTemp) / 2 + 10,// 77个中文字符2个英语字符=18个中文
                        heightTemp + fontSizeTemp + 20,
                        1);

            } catch (WriterException e) {

                throw new RuntimeException(e);
            }

            String resultPath = aliyunCloudStorageService.uploadSuffix(ImageUtils.bufferedImageToInputStream(bgImage, "png"), "/wwdcard", ".png");
            // 判断是否已存在，
            UserCard userCardPodb = getByUserId(param.getUserId());
            if (userCardPodb != null) {
                FileNeedDeleteTool.addAsync(userCardPodb.getPicUrl(),"用户重新生成卡片，原来卡片需要删除");
            }
            UserCard userCard = Optional.ofNullable(userCardPodb).orElse(new UserCard());
            userCard.setUserId(param.getUserId());
            userCard.setPicUrl(resultPath);
            userCard.setPicThumbUrl(resultPath);
            this.saveOrUpdate(userCard);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private ByteArrayInputStream download(String url, boolean userParam) throws IOException {
        HttpClient client = HttpClientTool.getCLIENT();
        String urlTemp = url;
        if (userParam) {
            urlTemp += "?x-oss-process=image/auto-orient,1";
        }
        HttpGet get = new HttpGet(urlTemp);

        HttpResponse httpResponse = client.execute(get);
        InputStream inputStream = httpResponse.getEntity().getContent();

        return StreamUtils.inputStreamToByteArrayInputStream(inputStream);
    }


}
